﻿using System.Linq;
using Daemon.Common;
using Daemon.Common.Helpers;
using Daemon.Infrustructure.EF;
using Daemon.Repository.EF.Enums;
using Daemon.Repository.Contract;
using Daemon.Model;
using System;
using System.Linq.Expressions;
using System.Collections.Generic;
using Daemon.Common.Const;

namespace Daemon.Repository.EF
{
	public class TakeAwayShopRepository : Repository<TakeAwayShop>, ITakeAwayShopRepository
	{
		protected override Expression<Func<TakeAwayShop, int>> PrimaryKeyExpression => r => r.Id;

		private readonly ITakeAwayShopCoordinateRepository _takeAwayShopCoordinateRepository;

		public TakeAwayShopRepository(ApiDBContent context, ITakeAwayShopCoordinateRepository takeAwayShopCoordinateRepository) : base(context)
		{
			_takeAwayShopCoordinateRepository = takeAwayShopCoordinateRepository;
		}

		protected override IEnumerable<TakeAwayShop> IncludeRelationships(IEnumerable<TakeAwayShop> entities, ApiDBContent db)
		{
			SetLocationInfo(entities);
			return base.IncludeRelationships(entities, db);
		}

		protected override void SaveRelationships(TakeAwayShop entity, TakeAwayShop entityWithRelationships, ApiDBContent db, short entityORMType)
		{
			if (RouteParameterHelper.CheckRouteParameter(RelationshipNames, TakeAwayShopRelationShipEnum.LocationInfo))
			{
				SaveCoordinate(entity, entityWithRelationships, entityORMType, db);
			}
		}

		private void SaveCoordinate(TakeAwayShop entity, TakeAwayShop entityWithRelationships, short entityORMType, ApiDBContent db)
		{
			var shopCoordinate = _takeAwayShopCoordinateRepository.FindAll().FirstOrDefault(r => r.ShopId == entity.Id);
			if (shopCoordinate != null)
			{
				shopCoordinate.Lat = entityWithRelationships.Lat;
				shopCoordinate.Lng = entityWithRelationships.Lng;
				_takeAwayShopCoordinateRepository.UpdateByDBContext(shopCoordinate, db);
			}
			else
			{
				shopCoordinate = new TakeAwayShopCoordinate() { Lat = entityWithRelationships.Lat, Lng = entityWithRelationships.Lng, ShopId = entity.Id };
				_takeAwayShopCoordinateRepository.AddByDBContext(shopCoordinate);
			}
		}

		private void SetLocationInfo(IEnumerable<TakeAwayShop> entities)
		{
			if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, TakeAwayShopRelationShipEnum.LocationInfo))
			{
				return;
			}

			var ids = entities.Select(r => r.Id).ToList();
			var locationInfo = _takeAwayShopCoordinateRepository.FindAll().Where(r => ids.Contains(r.ShopId)).ToDictionary(r => r.ShopId, r => r);
			foreach (var entity in entities)
			{
				if (locationInfo.TryGetValue(entity.Id, out TakeAwayShopCoordinate coordinate))
				{
					entity.Lat = coordinate.Lat;
					entity.Lng = coordinate.Lng;
				}
			}
		}
	}
}
